#include "stdafx.h"
#include <string.h>
#include <stdio.h>

#include "syscfg.h"
#include "sysarch.h"
#include "sysapi.h"
#include "ComAPI.h"
#include "sysfs.h"
#include "debugcfg.h"

bool SwapChar(char *pA, char *pB)
{
    if(pA == NULL || pB == NULL)
    {
        return false;
    }
    char c = *pA;
    *pA = *pB;
    *pB = c;
    return true;
}

bool SwapChar(BYTE *pA, BYTE *pB)
{
    if(pA == NULL || pB == NULL)
    {
        return false;
    }
    BYTE c = *pA;
    *pA = *pB;
    *pB = c;
    return true;
}

bool IsBcdCode(BYTE *p, WORD num)
{
    BYTE ch;

    for ( int i = 0; i < num; i++)
    {
        ch = p[i] & 0xf;
        if (ch > 9)
        {
            return false;
        }

        ch = p[i] >> 4;
        if (ch > 9)
        {
            return false;
        }
    }
    return true;
}

BYTE BcdToByte(BYTE bcd)
{
    return ((bcd >> 4) & 0x0f) * 10 + (bcd & 0x0f);
}


BYTE ByteToBcd(BYTE b)
{
    return (b / 10 << 4) + b % 10;
}

void ByteToBcd(BYTE b, BYTE *p)
{
    p[0] = (b / 10 << 4) + b % 10;
    p[1] = b / 100;
}

DWORD BcdToDWORD(BYTE* p, WORD len)
{
    BYTE* p0 = p;

    p += len - 1;

    DWORD val = 0;
    for (; p >= p0; p--)
    {
        val = val * 100 + ((*p >> 4) & 0x0f) * 10 + (*p & 0x0f);
    }

    return val;
}

DDWORD BcdToDDWORD(BYTE* p, WORD len)
{
    BYTE* p0 = p;

    p += len - 1;

    DDWORD val = 0;
    for (; p >= p0; p--)
    {
        val = val * 100 + ((*p >> 4) & 0x0f) * 10 + (*p & 0x0f);
    }

    return val;
}

void BcdToIP(BYTE* p, WORD len, BYTE *ip)
{
    ip[0] = ((*p >> 4) & 0x0f) * 10 + (*p & 0x0f);
    p++;

    ip[0] += (*p & 0x0f) * 100;


    ip[1] =  (*p & 0x0f);
    p++;

    ip[1] += ((*p >> 4) & 0x0f) * 100 + (*p & 0x0f) * 10;



    ip[2] = ((*p >> 4) & 0x0f) * 10 + (*p & 0x0f);
    p++;

    ip[2] += (*p & 0x0f) * 100;


    ip[3] =  (*p & 0x0f);
    p++;

    ip[3] += ((*p >> 4) & 0x0f) * 100 + (*p & 0x0f) * 10;
}


WORD ByteToWord(BYTE* pbBuf, WORD wLen)
{
    WORD val = 0;

    if (wLen > 2)
    {
        wLen = 2;
    }

    memcpy(&val, pbBuf, wLen);
    return val;
}

DWORD ByteToDWORD(BYTE* pbBuf, WORD wLen)
{
    DWORD val = 0;

    if (wLen > 4)
    {
        wLen = 4;
    }

    memcpy(&val, pbBuf, wLen);
    return val;
}

uint64 BcdToUint64(BYTE* p, WORD len)
{
    BYTE* p0 = p;

    p += len - 1;

    uint64 val = 0;
    for (; p >= p0; p--)
    {
        val = val * 100 + ((*p >> 4) & 0x0f) * 10 + (*p & 0x0f);
    }

    return val;
}


//����@len bcd���ֽڳ���
int BcdToInt(BYTE* p, WORD len)
{
    BYTE* p0 = p;

    p += len - 1;
    int val = (*p & 0x0f);

    bool fNeg;
    if ((*p & 0xf0) != 0)
    {
        fNeg = true;
    }
    else
    {
        fNeg = false;
    }

    p--;

    for (; p >= p0; p--)
    {
        val = val * 100 + ((*p >> 4) & 0x0f) * 10 + (*p & 0x0f);
    }

    if (fNeg)
    {
        return -val;
    }
    else
    {
        return val;
    }
}


void IntToBCD(int val, BYTE* bcd, WORD len)
{
    bool fNeg = false;

    if (val < 0)
    {
        val = -val;
        fNeg = true;
    }

    int power = 1;
    for (WORD i = 0; i < len - 1; i++)
    {
        power *= 100;
    }

    power *= 10;
    val %= power;

    power /= 10;

    if (fNeg)
    {
        bcd[len - 1] = 0x10 + val / power;
    }
    else
    {
        bcd[len - 1] = val / power;
    }

    len--;

    for (; len > 0; len--)
    {
        BYTE bHigh, bLow;
        val %= power;
        power /= 10;
        bHigh = val / power;

        val %= power;
        power /= 10;
        bLow = val / power;
        bcd[len - 1] = (bHigh << 4) | bLow;
    }
}

void DWORDToBCD(DWORD val, BYTE* bcd, WORD len)
{
    DWORD power;
    BYTE bHigh, bLow;

    memset(bcd, 0, len);
    if (len > 4) //��������ֽ�
    {
        power = 1000000000;
        bHigh = (BYTE )(val / power);
        val %= power;

        power = 100000000;
        bLow = (BYTE )(val / power);
        val %= power;
        bcd[4] = (bHigh << 4) | bLow;

        len = 4;
    }

    power = 1;
    for (WORD i = 0; i < len; i++)
    {
        power *= 100;
    }

    for (; len > 0; len--)
    {
        val %= power;
        power /= 10;
        bHigh = (BYTE )(val / power);

        val %= power;
        power /= 10;
        bLow = (BYTE )(val / power);
        bcd[len - 1] = (bHigh << 4) | bLow;
    }
}

void DWordToByte(DWORD val, BYTE* byte, WORD len)
{
    if ( len > 4 )
    {
        len = 4;
    }
    for (; len > 0; byte++, len--)
    {
        *byte = (BYTE)val % 0x100;
        val = val / 0x100;
    }
}

WORD DWordToByte(DWORD dw, BYTE* p)
{
    *p++ = dw & 0xff;
    *p++ = (dw >> 8) & 0xff;
    *p++ = (dw >> 16) & 0xff;
    *p = (dw >> 24) & 0xff;
    return 4;
}

DWORD ByteToDWord(BYTE* p)
{
    DWORD dw = 0;

    memcpy(&dw, p, 4);
    return dw;
    //return *p + (DWORD )*(p + 1)*0x100 + (DWORD )*(p + 2)*0x10000 + (DWORD )*(p + 3)*0x1000000;
}

void Uint64ToBCD(uint64 val, BYTE* bcd, WORD len)
{
    uint64 power;
    BYTE bHigh, bLow;

    memset(bcd, 0, len);

    power = 1;
    for (WORD i = 0; i < len; i++)
    {
        power *= 100;
    }

    for (; len > 0; len--)
    {
        val %= power;
        power /= 10;
        bHigh = (BYTE )(val / power);

        val %= power;
        power /= 10;
        bLow = (BYTE )(val / power);
        bcd[len - 1] = (bHigh << 4) | bLow;
    }
}

void HexToASCII(BYTE* in, BYTE* out, WORD wInLen)
{
    for (WORD i = 0; i < wInLen; i++)
    {
        BYTE b = *in++;
        BYTE hi = b >> 4;
        BYTE lo = b & 0x0f;
        if (hi >= 0x0a)
        {
            *out++ = hi - 0x0a + 'A';
        }
        else
        {
            *out++ = hi + '0';
        }

        if (lo >= 0x0a)
        {
            *out++ = lo - 0x0a + 'A';
        }
        else
        {
            *out++ = lo + '0';
        }
    }
}


void ByteToASCII(BYTE b, BYTE** pp)
{
    BYTE* p = *pp;

    BYTE hi = b >> 4;
    BYTE lo = b & 0x0f;

    if (hi >= 0x0a)
    {
        *p++ = hi - 0x0a + 'A';
    }
    else
    {
        *p++ = hi + '0';
    }

    if (lo >= 0x0a)
    {
        *p++ = lo - 0x0a + 'A';
    }
    else
    {
        *p++ = lo + '0';
    }

    *pp = p;
}


void ByteXtoASCII(BYTE b, BYTE** pp)
{
    BYTE* p = *pp;

    BYTE lo = b >> 4;
    BYTE hi = b & 0x0f;

    if (hi >= 0x0a)
    {
        *p++ = hi - 0x0a + 'A';
    }
    else
    {
        *p++ = hi + '0';
    }

    if (lo >= 0x0a)
    {
        *p++ = lo - 0x0a + 'A';
    }
    else
    {
        *p++ = lo + '0';
    }

    *pp = p;
}


BYTE AsciiToByte(BYTE** pp)
{
    BYTE* p = *pp;
    BYTE hi = 0, lo = 0;

    if (*p >= 'A' && *p <= 'F')
    {
        hi = *p - 'A' + 0x0a;
    }
    else if (*p >= 'a' && *p <= 'f')
    {
        hi = *p - 'a' + 0x0a;
    }
    else if (*p >= '0' && *p <= '9')
    {
        hi = *p - '0';
    }
    else
    {
        return 0;
    }

    p++;

    if (*p >= 'A' && *p <= 'F')
    {
        lo = *p - 'A' + 0x0a;
    }
    else if (*p >= 'a' && *p <= 'f')
    {
        lo = *p - 'a' + 0x0a;
    }
    else if (*p >= '0' && *p <= '9')
    {
        lo = *p - '0';
    }
    else
    {
        return hi;
    }

    p++;

    *pp = p;

    return (hi << 4) | lo;
}

bool IsAllAByte(const BYTE* p, BYTE b, WORD len)
{
    for (WORD i = 0; i < len; i++)
    {
        if (*p++ != b)
        {
            return false;
        }
    }

    return true;
}


// �������ж��Ƿ�ȫ��VAL�����Ϊ��Чֵ
bool IsAllAVal32(const int* piVal32, int32 iDstVal32, WORD wNum)
{
    for (WORD i = 0; i < wNum; i++)
    {
        if (piVal32[i] != iDstVal32)
        {

            return false;
        }
    }

    return true;
}

//�������ж��Ƿ�ȫ��VAL64�����Ϊ��Чֵ
bool IsAllAVal64(const int64* piVal64, int64 iDstVal64, WORD wNum)
{
    for (WORD i = 0; i < wNum; i++)
    {
        if (piVal64[i] != iDstVal64)
        {

            return false;
        }
    }

    return true;
}


//����������ȫ��VAL64�����ΪĿ��ֵ
void SetArrVal64(int64* piVal64, int64 iDstVal64, WORD wNum)
{
    for (WORD i = 0; i < wNum; i++)
    {
        piVal64[i] = iDstVal64;
    }
}

//����������ȫ��VAL64�����ΪĿ��ֵ
void SetArrVal32(int32* piVal32, int32 iDstVal32, WORD wNum)
{
    for (WORD i = 0; i < wNum; i++)
    {
        piVal32[i] = iDstVal32;
    }
}

WORD SearchStrBcd(char* pStart, char* pEnd, BYTE *pbBuf)
{
    bool fGetFirst = false;
    BYTE val = 0, i = 0;

    //BYTE *pTmp[32];

    while (pStart < pEnd)
    {
        char c = *pStart++;
        if (!fGetFirst)
        {
            if (c >= '0' && c <= '9')
            {
                fGetFirst = true;
            }
        }

        if (fGetFirst)
        {
            if (c >= '0' && c <= '9')
            {
                val = c - '0';
            }
            else
            {
                pbBuf[i++] = val;
                break;
            }

            c = *pStart++;
            if (c >= '0' && c <= '9')
            {
                val = val * 0x10 + c - '0';
            }
            else
            {
                pbBuf[i++] = val;
                break;
            }

            pbBuf[i++] = val;
            val = 0;
        }
    }

    return i;
}

WORD SearchStrVal(char* pStart, char* pEnd)
{
    bool fGetFirst = false;
    WORD val = 0;

    while (pStart < pEnd)
    {
        char c = *pStart++;
        if (!fGetFirst)
        {
            if (c >= '0' && c <= '9')
            {
                fGetFirst = true;
            }
        }

        if (fGetFirst)
        {
            if (c >= '0' && c <= '9')
            {
                val = val * 10 + c - '0';
            }
            else
            {
                break;
            }
        }

    }

    return val;
}

WORD SearchStrVal(char** ppStart, char* pEnd)
{
    bool fGetFirst = false;
    WORD val = 0;
    char *pStart = *ppStart;

    while (pStart < pEnd)
    {
        char c = *pStart++;
        if (!fGetFirst)
        {
            if (c >= '0' && c <= '9')
            {
                fGetFirst = true;
            }
        }

        if (fGetFirst)
        {
            if (c >= '0' && c <= '9')
            {
                val = val * 10 + c - '0';
            }
            else
            {
                break;
            }
        }

    }
    *ppStart = pStart;
    return val;
}


BYTE* bufbuf(BYTE* pbSrc, WORD wSrcLen, BYTE* pbSub, WORD wSubLen)
{
    BYTE* pbSrcEnd = pbSrc + wSrcLen;

    while (pbSrc + wSubLen <= pbSrcEnd)
    {
        if (memcmp(pbSrc, pbSub, wSubLen) == 0)
        {
            return pbSrc;
        }

        pbSrc++;
    }

    return NULL;
}

BYTE CheckSum(BYTE* p, WORD wLen)
{
    BYTE bSum = 0;

    for (; wLen > 0; wLen--)
    {
        bSum += *p++;
    }
    return bSum;
}
BYTE CRCCheck(BYTE bytDir, BYTE *abytCommOrder, WORD nStartPos, WORD nCheckLen)
{
    static int16 MSBInfo;
    static WORD wCrcData;
    static WORD nIndexI, nIndexJ;

    wCrcData = 0xffff;
    for (nIndexI = nStartPos; nIndexI < (nCheckLen + nStartPos); nIndexI++)
    {
        wCrcData = wCrcData ^ abytCommOrder[nIndexI];
        for (nIndexJ = 0; nIndexJ < 8; nIndexJ++)
        {
            MSBInfo = wCrcData & 0x0001;
            wCrcData = wCrcData  >> 1;
            if (MSBInfo != 0 )
            {
                wCrcData = wCrcData ^ 0xa001;
            }
        }
    }
    if (bytDir == 0)
    {
        abytCommOrder[nIndexI ] = wCrcData % 0x100;
        abytCommOrder[nIndexI + 1] = wCrcData / 0x100;
        return 0;
    }
    if (abytCommOrder[nIndexI ] != (wCrcData % 0x100))
    {
        return 1;
    }
    if (abytCommOrder[nIndexI + 1] != (wCrcData / 0x100))
    {
        return 1;
    }
    return 0;
}

void GetCurTime(TTime* pTime)
{
    GetSysTime(pTime);

    //Debug(DEBUG_COMMON, ("GetCurTime : %02d/%02d/%02d %02d::%02d::%02d. week=%d\r\n",
    //						pTime->nYear, pTime->nMonth, pTime->nDay,
    //				        pTime->nHour, pTime->nMinute, pTime->nSecond, pTime->nWeek));

    if (IsInvalidTime(*pTime))
    {
        Debug(DEBUG_CRITICAL, ("###error time %02d/%02d/%02d %02d::%02d::%02d.\r\n",
                          pTime->nYear, pTime->nMonth, pTime->nDay,
                          pTime->nHour, pTime->nMinute, pTime->nSecond));
    }
}


//���������ص�ǰ����2000/1/1 00:00:00 ������
DWORD GetCurTime()
{
    TTime now;

    GetCurTime(&now);

    return DaysFrom2000(now) * 60 * 60 * 24 +
           (DWORD )(now.nHour) * 60 * 60 +
           (DWORD )now.nMinute * 60 + now.nSecond;
}

//���������ص�ǰ����2000/1/1 00:00:00 �ķ�����
DWORD GetCurMinute()
{
    TTime now;

    GetCurTime(&now);

    return DaysFrom2000(now) * 60 * 24 +
           (DWORD )(now.nHour) * 60 +
           now.nMinute;
}


WORD g_wDaysOfMonth[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
//1   2   3   4   5   6   7   8   9   10  11  12

//�����������2000/1/1��year/month/day������
DWORD DaysFrom2000(const TTime& time)
{
    if (IsTimeEmpty(time))
    {
        return 0;
    }

    int y, m, d, days;
    y = BASETIME;
    m = 1;
    d = 1;

    days = 0;
    while (y < time.nYear)
    {
        if ((y % 4 == 0 && y % 100 != 0) || y % 400 == 0)   //����
        {
            days += 366;
        }
        else
        {
            days += 365;
        }

        y++;
    }

    //���ڣ�y == year
    while (m < time.nMonth)
    {
        if (m == 2)
        {
            if ((y % 4 == 0 && y % 100 != 0) || y % 400 == 0)   //����
            {
                days += 29;
            }
            else
            {
                days += 28;
            }

        }
        else
        {
            days += g_wDaysOfMonth[m - 1];
        }

        m++;
    }

    //���ڣ�m == month
    days += time.nDay - d;

    return days;
}

DWORD MinutesFrom2000(const TTime& rPast)
{
    DWORD dwPast = DaysFrom2000(rPast) * 60 * 24;

    dwPast += (DWORD )(rPast.nHour) * 60 + rPast.nMinute;

    return dwPast;
}

DWORD MonthFrom2000(const TTime& rPast)
{
    return (rPast.nYear - BASETIME) * 12 + rPast.nMonth - 1;
}


//һ�������0x1D5'5600
DWORD MonthsPast(const TTime& rPast, const TTime& rNow)
{
    DWORD dwPast = (rPast.nYear - BASETIME) * 12 + rPast.nMonth - 1;
    DWORD dwNow = (rNow.nYear - BASETIME) * 12 + rNow.nMonth - 1;

    if (dwNow <= dwPast)
    {
        return 0;
    }
    else
    {
        return dwNow - dwPast;
    }
}


//һ�������0x1D5'5600
int DaysPast(const TTime& rPast, const TTime& rNow)
{
    int iPast = (int )DaysFrom2000(rPast);
    int iNow = (int )DaysFrom2000(rNow);

    return iNow - iPast;
}

//һ�������0x1D5'5600
DWORD HoursPast(const TTime& rPast, const TTime& rNow)
{
    DWORD dwPast = DaysFrom2000(rPast) * 24;

    dwPast += rPast.nHour;

    DWORD dwNow = DaysFrom2000(rNow) * 24;
    dwNow += rNow.nHour;

    if (dwNow <= dwPast)
    {
        return 0;
    }
    else
    {
        return dwNow - dwPast;
    }
}

//һ�������0x1D5'5600
DWORD MinutesPast(const TTime& rPast, const TTime& rNow)
{
    DWORD dwPast = DaysFrom2000(rPast) * 60 * 24;

    dwPast += (DWORD )(rPast.nHour) * 60 + rPast.nMinute;

    DWORD dwNow = DaysFrom2000(rNow) * 60 * 24;
    dwNow += (DWORD )(rNow.nHour) * 60 + rNow.nMinute;

    if (dwNow <= dwPast)
    {
        return 0;
    }
    else
    {
        return dwNow - dwPast;
    }
}

/*
   int MunitesSub(const TTime& time1, const TTime& time2)
   {
    int t1 = DaysFrom2000(time1) * 60 * 24;
    t1 += (int )(time1.nHour)*60 + time1.nMinute;

    int t2 = DaysFrom2000(time2) * 60 * 24;
    t2 += (int )(time2.nHour)*60 + time2.nMinute;

    return t1 - t2;
   }*/


DWORD SecondsPast(const TTime& rPast, const TTime& rNow)
{
    DWORD dwPast = DaysFrom2000(rPast) * 60 * 60 * 24;

    dwPast += (DWORD )(rPast.nHour) * 60 * 60 + (DWORD )rPast.nMinute * 60 + rPast.nSecond;

    DWORD dwNow = DaysFrom2000(rNow) * 60 * 60 * 24;
    dwNow += (DWORD )(rNow.nHour) * 60 * 60 + (DWORD )rNow.nMinute * 60 + rNow.nSecond;

    if (dwNow <= dwPast)
    {
        return 0;
    }
    else
    {
        return dwNow - dwPast;
    }
}

bool IsInvalidTime(const TTime& time)
{
    if (time.nYear < 2000 || time.nYear > 2100 ||
        time.nMonth < 1 || time.nMonth > 12 ||
        time.nDay < 1 || time.nDay > 31 ||
        time.nHour > 23 ||
        time.nMinute >= 60 ||
        time.nSecond >= 60)
    {
        return true;
    }
    else
    {
        return false;
    }
}



void SecondsToTime(DWORD dwSeconds, TTime* pTime)
{
    int year = BASETIME, month = 1, day = 1, hour = 0, minute = 0, second = 0;
    DWORD delta;

    while (dwSeconds > 0)
    {
        if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0)   //����
        {
            delta = 366 * 24 * 60 * 60;
        }
        else
        {
            delta = 365 * 24 * 60 * 60;
        }

        if (dwSeconds < delta)
        {
            break;
        }
        else
        {
            dwSeconds -= delta;
            year++;
        }
    }


    while (dwSeconds > 0)
    {
        if (month == 2)
        {
            if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0)   //����
            {
                delta = 29 * 24 * 60 * 60;
            }
            else
            {
                delta = 28 * 24 * 60 * 60;
            }
        }
        else
        {
            delta = g_wDaysOfMonth[month - 1] * 24 * 60 * 60;
        }

        if (dwSeconds < delta)
        {
            break;
        }
        else
        {
            dwSeconds -= delta;
            month++;
        }
    }

    if (dwSeconds > 0)
    {
        day = dwSeconds / (24 * 60 * 60);

        dwSeconds -= day * 24 * 60 * 60;

        day++;

        if (dwSeconds > 0)
        {
            hour = dwSeconds / (60 * 60);

            dwSeconds -= hour * 60 * 60;

            if (dwSeconds > 0)
            {
                minute = dwSeconds / 60;
                second = dwSeconds - minute * 60;
            }
        }
    }

    pTime->nYear = year;
    pTime->nMonth = month;
    pTime->nDay = day;
    pTime->nHour = hour;
    pTime->nMinute = minute;
    pTime->nSecond = second;
//	pTime->nWeek = dayOfWeek(year, month, day) + 1;
    pTime->nWeek = DayOfWeek(*pTime);

}

void MinutesToTime(DWORD dwMins, TTime* pTime)
{
    SecondsToTime(dwMins * 60, pTime);
}

void DaysToTime(DWORD dwDays, TTime* pTime)
{
    SecondsToTime( dwDays * 24 * 3600, pTime );
}

void MonthsToTime(DWORD dwMonths, TTime* pTime)
{
    pTime->nYear = (WORD)( ( dwMonths / 12 ) + BASETIME );
    pTime->nMonth = (BYTE)( ( dwMonths % 12 ) + 1 );
    pTime->nDay = 1;
    pTime->nHour = 0;
    pTime->nMinute = 0;
    pTime->nSecond = 0;
}

/*
   int dayOfWeek(int year,int month,int day)
   {
    int _month[12]={31,0,31,30,31,30,31,31,30,31,30,31};
    if (year%4==0 && year%100!=0 || year%400==0)
       _month[1]=29;
    else _month[1]=28;
    int C=0;
    for (int i=0;i<month-1;++i)
      C+=_month[i];
    C+=day;
    int S=year-1+(year-1)/4-(year-1)/100+(year-1)/400+C;
    return S%7;
   }
 */

DWORD TimeToSeconds(const TTime& time)
{
    return DaysFrom2000(time) * 60 * 60 * 24 +
           (DWORD )(time.nHour) * 60 * 60 +
           (DWORD )time.nMinute * 60 + time.nSecond;
}

DWORD TimeToMinutes(const TTime& time)
{
    return DaysFrom2000(time) * 60 * 24 +
           (DWORD )(time.nHour) * 60 +
           time.nMinute;
}

bool IsTimeEmpty(const TTime& time)
{
    if (time.nYear == 0 && time.nMonth == 0 && time.nDay == 0 &&
        time.nHour == 0 && time.nMinute == 0 && time.nSecond == 0)
    {
        return true;
    }
    else
    {
        return false;
    }
}

//����:�Ƿ��ǲ�ͬ��һ��
bool IsDiffDay(const TTime& time1, const TTime& time2)
{
    if (time1.nDay != time2.nDay || time1.nMonth != time2.nMonth || time1.nYear != time2.nYear)
    {
        return true;
    }
    else
    {
        return false;
    }
}

//����:�Ƿ���ͬһ��
bool IsSameDay(const TTime& time1, const TTime& time2)
{
    if (time1.nDay == time2.nDay && time1.nMonth == time2.nMonth && time1.nYear == time2.nYear)
    {
        return true;
    }
    else
    {
        return false;
    }
}

//����:�Ƿ��ǲ�ͬ��һ��
bool IsDiffHour(const TTime& time1, const TTime& time2)
{
    if (time1.nHour != time2.nHour || time1.nDay != time2.nDay || time1.nMonth != time2.nMonth || time1.nYear != time2.nYear)
    {
        return true;
    }
    else
    {
        return false;
    }
}

void MinuteToBuf(const TTime& time, BYTE* pbBuf)
{
    *pbBuf++ = ByteToBcd(time.nYear % 100);
    *pbBuf++ = ByteToBcd(time.nMonth);
    *pbBuf++ = ByteToBcd(time.nDay);
    *pbBuf++ = ByteToBcd(time.nHour);
    *pbBuf++ = ByteToBcd(time.nMinute);
}

void BufToMinute(BYTE* pbBuf, TTime& time)
{
    time.nYear = 2000 + BcdToByte(*pbBuf++);
    time.nMonth = BcdToByte(*pbBuf++);
    time.nDay = BcdToByte(*pbBuf++);
    time.nHour = BcdToByte(*pbBuf++);
    time.nMinute = BcdToByte(*pbBuf++);
    time.nSecond = 0;
}

//DayOfWeek()�ķ��� 1 = Sunday, 2 = Monday, ..., 7 = Saturday
BYTE DayOfWeek(const TTime& time)
{
    DWORD dwDays = DaysFrom2000(time);
    WORD nWeek = (WORD )(dwDays % 7);

    nWeek = (nWeek + BASEWEEK) % 7;
    return nWeek + 1;
}


//����:
//		@iIntervV ������ݼ���ʱ����,ȡ������
bool AddIntervs(TTime& time, BYTE bIntervU, int iIntervV)
{
    int nYear, nMonth;
	int y;
    DWORD dwSec = TimeToSeconds(time);

    switch (bIntervU)
    {
    case TIME_UNIT_MINUTE:
        dwSec += (DWORD )60 * iIntervV;
        SecondsToTime(dwSec, &time);
        return true;

    case TIME_UNIT_HOUR:
        dwSec += (DWORD )60 * 60 * iIntervV;
        SecondsToTime(dwSec, &time);
        return true;

    case TIME_UNIT_DAY:
        dwSec += (DWORD )24 * 60 * 60 * iIntervV;
        SecondsToTime(dwSec, &time);
        return true;

    case TIME_UNIT_MONTH:
        nYear = iIntervV / 12;
        time.nYear = time.nYear + nYear;

        iIntervV = iIntervV % 12;
        nMonth = iIntervV + time.nMonth;       //�Ȱ�month���з�����
        if (nMonth > 12)
        {
            time.nYear++;
            nMonth -= 12;
        }
        else if (nMonth < 1)
        {
            time.nYear--;
            nMonth += 12;
        }

        time.nMonth = nMonth;

		//if (time.nDay > g_wDaysOfMonth[nMonth-1])
		//{
		//	time.nDay = g_wDaysOfMonth[nMonth-1];
		//}

		y = time.nYear;
		if (time.nMonth == 2) 
		{
			if ((y % 4 == 0 && y % 100 != 0) || y % 400 == 0)   //����
			{
				if (time.nDay > 29) 
					time.nDay = 29;
			}
			else if (time.nDay > 28) 
				time.nDay = 28;
		}
		else if ((time.nMonth == 4) || (time.nMonth == 6) || (time.nMonth == 9) || (time.nMonth == 11))
		{
			if (time.nDay > 30)
				time.nDay = 30;
		}
		
        return true;

    default: return false;
    }

    return false;
}


//����:�����ڵ�ʱ��tmNow��Թ�ȥ��ʱ��tmPast�Ѿ����ŵĲ���������,�������Ѽ����λ����
//		��ʱ����Ե�,���������ʱ������,���ʱ������Ե�
int IntervsPast(const TTime& tmPast, const TTime& tmNow, BYTE bIntervU, BYTE bIntervV)
{
    if (bIntervV == 0)
    {
        return 0;
    }

    DWORD dwPast = TimeToSeconds(tmPast);
    DWORD dwNow = TimeToSeconds(tmNow);
    TTime now, past;
    int iSign = 1;
    if (dwNow == dwPast)
    {
        return 0;
    }
    else if (dwNow > dwPast)
    {
        now = tmNow;
        past = tmPast;
    }
    else
    {
        iSign = -1;
        now = tmPast;
        past = tmNow;
    }

    switch (bIntervU)
    {
    case TIME_UNIT_MINUTE:
        return iSign * (int )(MinutesPast(past, now) / bIntervV);

    case TIME_UNIT_HOUR:
        return iSign * (int )(HoursPast(past, now) / bIntervV);

    case TIME_UNIT_DAY:
        return iSign * (int )(DaysPast(past, now) / bIntervV);

    case TIME_UNIT_MONTH:
        return iSign * (int )(MonthsPast(past, now) / bIntervV);
    default: return 0;
    }

    return 0;
}

//����:��ȡ���µ�����
BYTE DaysOfMonth(TTime time)
{
    TTime tm = time;
    DWORD dwDays1, dwDays2;

    tm.nDay = 1;
    dwDays1 = DaysFrom2000(tm);

    if (tm.nMonth == 12)
    {
        tm.nYear++;
        tm.nMonth = 1;
    }
    else
    {
        tm.nMonth++;
    }
    dwDays2 = DaysFrom2000(tm);

    return (BYTE)(dwDays2 - dwDays1);
}

DWORD GetMonthStart(TTime time)
{
    time.nDay = 1;
    time.nHour = 0;
    time.nMinute = 0;
    time.nSecond = 0;

    return TimeToSeconds(time);
}

DWORD GetMonthEnd(TTime time)
{
    time.nDay = 1;
    time.nHour = 0;
    time.nMinute = 0;
    time.nSecond = 0;
    AddIntervs(time, TIME_UNIT_MONTH, 1);

    return TimeToSeconds(time);
}

//������ĳʱ�̶�Ӧ�ļ���Ŀ�ʼʱ�估�������ʱ�������
//@time		ĳʱ�̵�ʱ��
//@bType	Ҫת���ļ��������
//@dwStartS �����𱾼�����͵���ʼʱ�������
//@dwEndS   �����𱾼�����͵Ľ���ʱ�������
//@dwIntvT  ������ʱ��ķ�����ֻ���ڼ������Ϊ���ӻ�Сʱʱ���糭������15���Ӽ����,�������¿�ȱʡ������
void TimeToIntervS(TTime time, BYTE bType, DWORD& dwStartS, DWORD& dwEndS, DWORD dwIntvT)
{
    TTime tm = time;

    switch (bType)
    {
    case TIME_UNIT_MINUTE:
        if (dwIntvT != 0)
        {
            dwStartS = TimeToMinutes(tm) / dwIntvT * dwIntvT * 60;
            dwEndS = dwStartS + dwIntvT * 60;
        }
        break;
    case TIME_UNIT_HOUR:
        if (dwIntvT != 0)
        {
            dwStartS = TimeToMinutes(tm) / (60 * dwIntvT) * dwIntvT * 60 * 60;
            dwEndS = dwStartS + dwIntvT * 60 * 60;
        }
        break;
    case TIME_UNIT_DAY:
        tm.nHour = 0;
        tm.nMinute = 0;
        tm.nSecond = 0;
        dwStartS = TimeToSeconds(tm);
        dwEndS = dwStartS + 24 * 60 * 60;
        break;
    case TIME_UNIT_MONTH:
        tm.nDay = 1;
        tm.nHour = 0;
        tm.nMinute = 0;
        tm.nSecond = 0;
        dwStartS = TimeToSeconds(tm);
        dwEndS = dwStartS + (DWORD)DaysOfMonth(tm) * 24 * 60 * 60;
        break;
    default:
        break;;
    }
}
bool AutoLoopWriteFile(char* pszPathName, BYTE* pbData, DWORD dwLen, DWORD dwTotalLen)
{
    bool fRet = true;
    int fp = open(pszPathName, O_CREAT | O_RDWR | O_BINARY, S_IREAD | S_IWRITE);

    //windows�±���ʹ��O_BINARY,����������ĳ���Ϊ��,����ϵͳ��O_BINARYΪ��

    if (fp < 0)
    {
        Debug(DEBUG_CRITICAL, ("WriteFile err!! fail to open %s.\r\n", pszPathName));
        return false;
    }
    else
    {
        //int nFileSize = fseek(fp, 0, SEEK_END);
        lseek(fp, 0, SEEK_SET);
        DWORD dwFileCurPos = 0;
        read(fp, (BYTE*)&dwFileCurPos, 4);

        if (dwFileCurPos > dwTotalLen)
        {
            dwFileCurPos = 4;
        }

        lseek(fp, dwFileCurPos, SEEK_SET);
        ssize_t retLen = write(fp, pbData, dwLen);
        if (retLen<=0 || (DWORD)retLen!=dwLen)
        {
            Debug(DEBUG_CRITICAL, ("WriteFile err!  fail to write %s .\r\n", pszPathName));
            fRet = false;
        }

        lseek(fp, 0, SEEK_SET);
        dwFileCurPos += dwLen;
        write(fp, (BYTE*)&dwFileCurPos, 4);
    }
    close(fp);

    return fRet;
}

bool WriteFile(char* pszPathName, BYTE* pbData, DWORD dwLen)
{
    bool fRet = true;
    int f = open(pszPathName, O_CREAT | O_RDWR | O_BINARY, S_IREAD | S_IWRITE);

    //windows�±���ʹ��O_BINARY,����������ĳ���Ϊ��,����ϵͳ��O_BINARYΪ��

    if (f < 0)
    {
        Debug(DEBUG_CRITICAL, ("WriteFile err!! fail to open %s.\r\n", pszPathName));
        return false;
    }
    else
    {
        int nFileSize = lseek(f, 0, SEEK_END);
        if (nFileSize > (int )dwLen)
        {
            close(f);
            unlink(pszPathName);   //ɾ��
            f = open(pszPathName, O_CREAT | O_RDWR, S_IREAD | S_IWRITE);  //���´��� , S_IREAD|S_IWRITE
            if (f < 0)
            {
                return false;
            }
        }
        else
        {
            lseek(f, 0, SEEK_SET);
        }

        if (write(f, pbData, dwLen) != (int )dwLen)
        {
            Debug(DEBUG_CRITICAL, ("WriteFile err!  fail to write %s .\r\n", pszPathName));
            fRet = false;
        }
    }
    close(f);

    return fRet;
}

bool PartWriteFile(char* pszPathName, DWORD dwOff, BYTE* pbData, DWORD wLen)
{
    bool fRet = true;

    int f = open(pszPathName, O_CREAT | O_RDWR | O_BINARY, S_IREAD | S_IWRITE);

    if (f < 0)
    {
        Debug(DEBUG_CRITICAL, ("SaveFile : error : fail to open %s.\r\n", pszPathName));
        return false;
    }
    else
    {
        lseek(f, dwOff, SEEK_SET);
        if (write(f, pbData, wLen) != (int )wLen)
        {
            Debug(DEBUG_CRITICAL, ("SaveFile : error:  fail to write %s .\r\n", pszPathName));
            fRet = false;
        }
    }
    close(f);

#ifdef SYS_WIN32
    FILE *p;
    char name[200];
    GetWin32FileName(pszPathName, name);
    if ( (p = fopen(name, "w+")) != NULL )
    {
        fseek(p, dwOff, SEEK_SET);
        fwrite(pbData, 1, wLen, p);
        fclose(p);
    }
#endif
    return fRet;
}

bool PartReadFile(char* pszPathName, DWORD dwOffset, BYTE *pbData, DWORD dwLen)
{
    bool fRet = true;

    int f = open(pszPathName, O_RDWR | O_BINARY, S_IREAD | S_IWRITE);

    if (f < 0)
    {
        Debug(DEBUG_CRITICAL, ("PartReadFile : error : fail to open %s.\r\n", pszPathName));
        return false;
    }
    else
    {
        lseek(f, dwOffset, SEEK_SET);
        if (read(f, pbData, dwLen) != (int )dwLen)
        {
            Debug(DEBUG_CRITICAL, ("PartRaedFile : error:  fail to read %s .\r\n", pszPathName));
            fRet = false;
        }
    }
    close(f);

    return fRet;
}

bool DeleteFile(char* pszPathName)
{
    int f = open(pszPathName, O_RDWR, S_IREAD | S_IWRITE);

    if (f < 0)
    {
        return true;
    }

    close(f);
    if ( unlink(pszPathName) < 0 )   //ɾ��
    {
        return false;
    }
    else
    {
#ifdef SYS_WIN32
        FILE *p;
        char name[200];
        GetWin32FileName(pszPathName, name);
        //delete(name);
        if ( (p = fopen(name, "w")) != NULL )
        {
            fclose(p);
        }
#endif
        return true;
    }
}

bool ReadFile(char* pszPathName, BYTE* pbData, DWORD dwBytesToRead)
{
    bool fRet = false;
    int nFileSize;
    int f = open(pszPathName, O_RDWR | O_BINARY, S_IREAD | S_IWRITE);  //,|O_BINARY S_IREAD|S_IWRITE

    if (f >= 0)
    {
        nFileSize = lseek(f, 0, SEEK_END);
        if (nFileSize>0 && (DWORD)nFileSize==dwBytesToRead)
        {
            lseek(f, 0, SEEK_SET);
            int rdLen = read(f, pbData, dwBytesToRead);
            if (rdLen>0 &&  (DWORD)rdLen==dwBytesToRead)
            {
                fRet = true;
            }
            else
            {
                Debug(DEBUG_CRITICAL, ("ReadFile : error : fail to read %s.\r\n", pszPathName));
            }
            close(f);
        }
        else
        {
            close(f);
            unlink(pszPathName);   //ɾ��
        }
    }

    return fRet;
}

//����:��ȡ�ļ�,�ļ����Ȳ���ϵ�ʱ��ɾ���ļ�
//����:@pszPathName ·���ļ���
//	   @pbData ��Ŷ������ļ�����
//	   @dwMaxBytesToRead ���������ļ�����
//����:�����ȷ�򷵻ض����ĳ���,���򷵻�-1��ʾ�ļ��򿪻��߶�ȡ����,-2��ʾ�ļ����
int readfile(char* pszPathName, BYTE* pbData, DWORD dwMaxBytesToRead)
{
    int iRet = -1;
    int nFileSize;
    int f = open(pszPathName, O_RDWR | O_BINARY, S_IREAD | S_IWRITE);  //,|O_BINARY S_IREAD|S_IWRITE

    if (f >= 0)
    {
        nFileSize = lseek(f, 0, SEEK_END);
        if (nFileSize <= (int )dwMaxBytesToRead)
        {
            lseek(f, 0, SEEK_SET);
            if (read(f, pbData, nFileSize) == nFileSize)
            {
                iRet = nFileSize;
            }
            else
            {
                Debug(DEBUG_CRITICAL, ("ReadFile : error : fail to read %s.\r\n", pszPathName));
            }
            close(f);
        }
        else
        {
            iRet = -2;
            close(f);
            unlink(pszPathName);   //ɾ��
        }
    }

    return iRet;
}

int GetFileLen(char* pszPathName)
{
    int iFileSize = -1;
    int f = open(pszPathName, O_RDWR, S_IREAD | S_IWRITE); //, S_IREAD|S_IWRITE

    if (f >= 0)
    {
        iFileSize = lseek(f, 0, SEEK_END);
        close(f);
    }

    return iFileSize;
}

#ifndef SYS_VDK

/*
 * FCS lookup table as calculated by genfcstab.
 */
static const u_short fcstab[256] = {
    0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
    0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
    0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
    0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
    0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
    0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
    0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
    0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
    0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
    0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
    0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
    0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
    0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
    0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
    0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
    0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
    0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
    0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
    0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
    0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
    0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
    0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
    0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
    0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
    0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
    0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
    0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
    0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
    0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
    0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
    0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
    0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
};

WORD pppfcs16(WORD fcs, unsigned char * cp, int len)
{
    while (len--)
    {
        fcs = (fcs >> 8) ^ fcstab[(fcs ^ *cp++) & 0xff];
    }
    return fcs;
}


#endif //SYS_VDK

static unsigned short crc_16_table[16] = {
    0x0000, 0xCC01, 0xD801, 0x1400, 0xF001, 0x3C00, 0x2800, 0xE401,
    0xA001, 0x6C00, 0x7800, 0xB401, 0x5000, 0x9C01, 0x8801, 0x4400
};


WORD get_crc_16(WORD start, BYTE *p, int n)
{
    WORD crc = start;
    register WORD r;

    /* while there is more data to process */
    while (n-- > 0)
    {
        /* compute checksum of lower four bits of *p */
        r = crc_16_table[crc & 0xF];
        crc = (crc >> 4) & 0x0FFF;
        crc = crc ^ r ^ crc_16_table[*p & 0xF];

        /* now compute checksum of upper four bits of *p */
        r = crc_16_table[crc & 0xF];
        crc = (crc >> 4) & 0x0FFF;
        crc = crc ^ r ^ crc_16_table[(*p >> 4) & 0xF];

        /* next... */
        p++;
    }
    return crc;
}


#define CRC_CODE ((unsigned long)0x04C11DB7)
DWORD sub_cal_crc32( unsigned char * data, unsigned int data_len )
{
    unsigned long crc = 0x00000000;
    unsigned int i, j;
    unsigned char dat;

    for ( i = 0; i < data_len; i++ )
    {
        dat = data[i];
        crc ^= ((unsigned long)dat) << 24;
        for ( j = 0; j < 8; j++ )
        {
            if ( crc & 0x80000000 )
            {
                crc <<= 1;
                crc ^= CRC_CODE;
            }
            else
            {
                crc <<= 1;
            }
        }
    }
    return crc;
}

/* Convert numeric IP address into decimal dotted ASCII representation.
 * returns ptr to static buffer; not reentrant!
 */
#ifdef SYS_VDK
void addrntoa(DWORD s_addr, char* str)
{
    //static char str[16];
    //u32_t s_addr = addr.s_addr;
    char inv[3];
    char *rp;
    u8_t *ap;
    u8_t rem;
    u8_t n;
    u8_t i;

    rp = str;
    ap = (u8_t*)&s_addr;
    for (n = 0; n < 4; n++)
    {
        i = 0;
        do
        {
            rem = *ap % (u8_t)10;
            *ap /= (u8_t)10;
            inv[i++] = '0' + rem;
        }
        while (*ap);
        while (i--)
        {
            *rp++ = inv[i];
        }
        *rp++ = '.';
        ap++;
    }
    *--rp = 0;
    //return str;
}
#endif

//����:���򿽱�
void revcpy(BYTE* pbDst, const BYTE* pbSrc, WORD wLen)
{
    pbSrc += wLen - 1;
    for (WORD i = 0; i < wLen; i++)
    {
        *pbDst++ = *pbSrc--;
    }
}

//����:���򿽱�
//����:< 0 buf1 less than buf2
//		 0 buf1 identical to buf2
//	   > 0 buf1 greater than buf2
int revcmp(const void *buf1, const void *buf2, int count)
{
    const BYTE* p1 = (BYTE* )buf1;
    const BYTE* p2 = (BYTE* )buf2;

    p1 += count - 1;
    p2 += count - 1;

    for (; count > 0; count--)
    {
        if (*p1 > *p2)
        {
            return 1;
        }
        else if (*p1 < *p2)
        {
            return -1;
        }

        p1--;
        p2--;
    }

    return 0;
}

//����:�Ի������ֽڽ��е��򿽱�
void RevBuf(BYTE* pbBuf, WORD wLen)
{
    BYTE* pbEnd = pbBuf + wLen - 1;

    wLen /= 2;

    BYTE b;
    for (WORD i = 0; i < wLen; i++, pbBuf++, pbEnd--)
    {
        b = *pbBuf;
        *pbBuf = *pbEnd;
        *pbEnd = b;
    }
}

//X-DER ��ݳ�����ɳ��ȱ���
BYTE EncodeLength(int len, BYTE *p)
{
    if (len < 128)
    {
        *p = len;
        return 1;
    }
    else
    {
        BYTE i, k = 4, ch[4];
        ch[0] = (BYTE)(len >> 24);
        ch[1] = (BYTE)(len >> 16);
        ch[2] = (BYTE)(len >> 8);
        ch[3] = (BYTE)len;

        for (i = 0; i < 4; i++)
        {
            if (ch[i] == 0)
            {
                k--;
            }
            else
            {
                break;
            }
        }

        *p++ = 0x80 | k;
        for (i = 0; i < k; i++)
        {
            *p++ = ch[4 - k + i];
        }

        return k + 1;
    }
}

//X-DER �Գ�����ɽ���
int DecodeLength(BYTE *pbBuf, DWORD *pdwNum)
{
    if ( *pbBuf < 128 )
    {
        *pdwNum = *pbBuf;
        return 1;
    }
    else
    {
        BYTE n = (*pbBuf++) & 0x7f;
        if ( n > 4 )
        {
            return -1;
        }

        DWORD val = 0;
        for ( BYTE i = 0; i < n; i++ )
        {
            val = (val << 8) | (*pbBuf++);
        }
        *pdwNum = val;
        return n + 1;
    }
}

//���ֽڰ�λ���е���
BYTE ByteBitReverse(BYTE b)
{
    BYTE b0 = 0;
    BYTE bMark = 0x80;

    for (BYTE b1 = 8; b1 > 0; b1--)
    {
        if ((b & 0x01) == 0x01)
        {
            b0 |= bMark;
        }

        bMark >>= 1;
        b >>= 1;
    }

    return b0;
}

//���ֽڴ����ֽ�Ϊ��λ���е���
void BufByteReverse(BYTE *bBuf, WORD wLen)
{
    BYTE *bBuf0 = bBuf + wLen - 1;

    while (bBuf0 > bBuf)
    {
        *bBuf ^= *bBuf0;
        *bBuf0 ^= *bBuf;
        *bBuf++ ^= *bBuf0--;
    }
}

//���ֽڴ���λΪ��λ���е���
void BufBitReverse(BYTE *bBuf, WORD wLen)
{
    BufByteReverse(bBuf, wLen);
    while (wLen-- > 0)
    {
        *bBuf = ByteBitReverse(*bBuf);
        bBuf++;
    }
}

int64 Pow(int iBase, WORD wExp)
{
    int64 iVal = 1;

    for (WORD i = 0; i < wExp; i++)
    {
        iVal *= iBase;
    }

    return iVal;
}

//����:��ʱ��ת���ɿ�����ʾ���ַ�
//����:@time ��ת����ʱ��
//	   @psz �������ת������ַ�
//����:ת����õ����ַ�
char* TimeToStr(const TTime& time, char* psz)
{
    sprintf(psz, "%04d-%02d-%02d %02d:%02d:%02d",
            time.nYear, time.nMonth, time.nDay,
            time.nHour, time.nMinute, time.nSecond);

    return psz;
}

//����:��ʱ��ת���ɿ�����ʾ���ַ�
//����:@dwTime	��ת����ʱ��
//	   @psz		�������ת������ַ�
//����:ת����õ����ַ�
char* TimeToStr(DWORD dwTime, char* psz)
{
    TTime tmTime;

    SecondsToTime(dwTime, &tmTime);

    return TimeToStr(tmTime, psz);
}

char* MtrAddrToStr(const BYTE* pbAddr, char* psz)
{
    sprintf(psz, "%02x%02x%02x%02x%02x%02x",
            pbAddr[5], pbAddr[4], pbAddr[3], pbAddr[2], pbAddr[1], pbAddr[0]);

    return psz;
}

BYTE* GetSubPos(BYTE *src, WORD wSrcLen, BYTE *dst, WORD wDstLen)
{
    int i, j;

    for (i = 0; i <= wSrcLen - wDstLen; i++)
    {
        if (src[i] == dst[0])
        {
            j = 1;
            while (src[i + j] == dst[j] && j < wDstLen)
            {
                j++;
            }
            if (j == wDstLen)
            {
                return src + i;
            }
        }
    }
    return NULL;
}


//����:����һ���������еı���Ϊ1��λ�ĸ���
WORD CalcuBitNum(const BYTE* pbBuf, WORD wSize)
{
    static WORD wBitNumArr[16] = { 0, 1, 1, 2, 1, 2, 2, 3, //0~7
                                   1, 2, 2, 3, 2, 3, 3, 4 }; //8~15

    WORD wBitNum = 0;
    BYTE b;

    for (WORD i = 0; i < wSize; i++)
    {
        b = *pbBuf++;
        wBitNum += wBitNumArr[b & 0x0f];
        wBitNum += wBitNumArr[(b >> 4) & 0x0f];
    }

    return wBitNum;
}

//����:���������������,���ص���һ��������
void AndTwoBuf(BYTE* p1, const BYTE* p2, WORD wSize)
{
    for (WORD i = 0; i < wSize; i++, p1++, p2++)
    {
        *p1 = *p1 & *p2;
    }
}

//����:����������������,���ص���һ��������
void XorTwoBuf(BYTE* p1, const BYTE* p2, WORD wSize)
{
    for (WORD i = 0; i < wSize; i++, p1++, p2++)
    {
        *p1 = *p1 ^ *p2;
    }
}

//����:��������������,���ص���һ��������
void OrTwoBuf(BYTE* p1, const BYTE* p2, WORD wSize)
{
    for (WORD i = 0; i < wSize; i++, p1++, p2++)
    {
        *p1 = *p1 | *p2;
    }
}


#ifdef SYS_LINUX
bool IsMountedOK(char *str)
{
    DIR *d = opendir(str); //str====/opt/usb

    if (d == NULL)
    {
        Debug(DEBUG_CRITICAL, ("%s no exit\r\n", str));
        return false;
    }
    char str2[64];
    sprintf(str2, "%s/..", str);
    struct stat s1;
    struct stat s2;
    lstat(str, &s1);
    lstat(str2, &s2);
    if (s1.st_dev != s2.st_dev)
    {
        return true;
    }
    if (s1.st_ino == s2.st_ino)
    {
        return true;
    }

    return false;
}
#endif

bool UsbUpdate(char* szPath)
{
#ifdef SYS_LINUX
    WORD i;
    char str[64];
    strcpy(str, "/opt/usb");

    for (i = 0; i < 10; i++)
    {
        //�ȼ��U���Ƿ��Ѿ����سɹ�
        if (IsMountedOK(str))
        {
            Debug(DEBUG_CRITICAL, ("USB mounted OK\r\n"));
            break;
        }
        system("mkdir /opt/usb");
        system("mount -t vfat /dev/sda1 /opt/usb");
        system("mount -t vfat /dev/sda /opt/usb");
        Sleep(1500);
        continue;
    }
    if (i == 10) //����U��ʧ��
    {
        return false;
    }
    sprintf(str, "/opt/usb/%s", szPath);

    char command[64];
    sprintf(command, "cp -f %s/update /opt/app", str);
    system(command);

    system("chmod +x /opt/app/update");
    sprintf(command, "source /opt/app/update %s", str);
    system(command);
    Sleep(5000);
    system("umount /opt/usb");
    strcpy(str, "/opt/app/update");
    int f = open(str, O_RDWR | O_BINARY, S_IREAD | S_IWRITE);
    if (f >= 0)
    { //��ɹ�
        close(f);
        system("rm -Rf /opt/app/update");
        return true;
    }
    else
    { //��ʧ��
        return false;
    }
#endif
    return true;
}


const unsigned char HexData[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
unsigned char asctohex(unsigned char asciidata)
{
    unsigned int i;

    for (i = 0; i < 16; i++)
    {
        if (HexData[i] == asciidata)
        {
            return i;
        }
    }

    return 0;
}

void ASCIIToHex(unsigned char * pAsciiData, unsigned short len, unsigned char * pHexBuff)
{
    unsigned int i;

    if (len == 0)
    {
        return;
    }
    if (len % 2)
    {
        len += 1;
    }
    for (i = 0; i < len / 2; i++)
    {
        pHexBuff[i] = asctohex(pAsciiData[i * 2]);
        pHexBuff[i] = (pHexBuff[i] << 4) & 0xf0;
        pHexBuff[i] += asctohex(pAsciiData[i * 2 + 1]);
    }
}

void HexToASCII(unsigned char * pHexBuff, unsigned short len, unsigned char * pAsciiData)
{
    unsigned int i;

    if (len == 0)
    {
        return;
    }
    for (i = 0; i < len; i++)
    {
        pAsciiData[i * 2] = HexData[((pHexBuff[i] >> 4) & 0x0f)];
        pAsciiData[i * 2 + 1] = HexData[(pHexBuff[i] & 0x0f)];
        pAsciiData[i * 2 + 2] = 0;
    }
}


unsigned short WordToBcd(unsigned short num)
{
    unsigned short bcd;

    num = num % 10000;
    bcd = num / 1000;
    num = num % 1000;
    bcd <<= 4;
    bcd += num / 100;
    num = num % 100;
    bcd <<= 4;
    bcd += num / 10;
    bcd <<= 4;
    bcd += num % 10;
    return bcd;
}

void Anticpy(BYTE *bDstAddr, const BYTE *bSrcAddr, WORD wLen)
{
    for (int i = 0; i < wLen; i++)
    {
        bDstAddr[i] = bSrcAddr[wLen - i - 1];
    }
}

void SearchStrcNum(char** ppStart, char* pEnd , char * cNumber)//10����
{
	bool fGetFirst = false;
	char *pStart = *ppStart;
	BYTE i = 0;
	while (pStart < pEnd)
	{
		char c = *pStart++;
		if (!fGetFirst)
		{
			if (c>='0' && c<='9')
			{
				fGetFirst = true;
			}
		}

		if (fGetFirst)
		{
			if (c>='0' && c<='9' && i < 20)
			{
				i++;
				*cNumber++ = c;
				Debug(DEBUG_COMMON, ("Gprs: get number = %c!!!!!!!!.\r\n", *(cNumber-1)));
			}
			else
			{
				break;
			}
		}

	}
	*ppStart = pStart;
}

WORD SearchStrValHex(char** ppStart, char* pEnd)//16����
{
	bool fGetFirst = false;
	WORD val = 0;
	char *pStart = *ppStart;
	while (pStart < pEnd)
	{
		char c = *pStart++;
		if (!fGetFirst)
		{
			if ((c>='0' && c<='9') || (c>='A' && c<='F') || (c>='a' && c<='f'))
			{
				fGetFirst = true;
			}
		}

		if (fGetFirst)
		{
			if (c>='0' && c<='9')
			{
				val = val*16 + c - '0';
			}
			else if(c>='A' && c<='F')
			{
				val = val*16 + c - 'A' + 10;
			}
			else if(c>='a' && c<='f')
			{
				val = val*16 + c - 'a' + 10;
			}
			else
			{
				break;
			}
		}

	}
	*ppStart = pStart;	
	return val;
}


bool SearchMtrAckFrm(BYTE *pbRetFrm, BYTE wRetLen, BYTE *pbMtrAddr, DWORD dwID)
{
	for (int i = 0; i < wRetLen; i++)
	{
		if (pbRetFrm[i] == 0x68 && pbRetFrm[i + 7] == 0x68 &&
			memcmp(pbMtrAddr, &pbRetFrm[i + 1], 6) == 0)
		{
			return true;
/*
			if (pbRetFrm[i + 7 + 2] < 4)
			{
				bLen = 2;
			}
			else //if(pbRetFrm[i + 7 + 2] >= 4)
			{
				bLen = 4;
			}

			memcpy(bIDBuf, &dwID, bLen);
			for (int i = 0; i < bLen; i++)
			{
				bIDBuf[i] += 0x33;
			}
			if (memcmp(bIDBuf, &pbRetFrm[i + 7 + 3], bLen) == 0)
			{
				wOffset = i;
				//memcpy(pbBuf, pbRetFrm + wOffset, wRetLen - wOffset);
				DebugBuf(DEBUG_COMMON, "Mtr 645 Frm<--", pbRetFrm + wOffset, wRetLen - wOffset);
				//return wRetLen - wOffset;
				return true;
			}
*/
		}
	}

	return false;
}


bool GetMtrFrmInfo(BYTE *pbRetFrm, BYTE wRetLen, BYTE *pbMtrAddr, DWORD &dwID)
{
	BYTE bLen = 0;
	BYTE bIDBuf[4];
	
	dwID = 0;
	for (int i = 0; i < wRetLen; i++)
	{
		if (pbRetFrm[i] == 0x68 && pbRetFrm[i + 7] == 0x68)
		{
			memcpy(pbMtrAddr, &pbRetFrm[i + 1], 6);
			Debug(DEBUG_COMMON, ("GetMtrFrmInfo Mtr Addr 0x%02x%02x%02x%02x%02x%02x\r\n", pbMtrAddr[5],pbMtrAddr[4],pbMtrAddr[3],pbMtrAddr[2],pbMtrAddr[1],pbMtrAddr[0]));

			if (pbRetFrm[i + 7 + 2] < 4)
			{
				bLen = 2;
			}							
			else //if ((pbRetFrm[i + 7 + 2] >= 4)
			{
				bLen = 4;
			}

			memcpy(bIDBuf, &pbRetFrm[i + 7 + 3], bLen);
			for (int i = 0; i < bLen; i++)
			{
				bIDBuf[i] -= 0x33;
			}
			memcpy(&dwID, bIDBuf, bLen);
			Debug(DEBUG_COMMON, ("GetMtrFrmInfo Mtr ID 0x%08x\r\n", dwID));
			return true;
		}
	}

	return false;
}
